package com.runccyy.utils;

import com.google.gson.JsonParser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;


public class WeChatUtil {

    @Value("${wx.appid}")
    private String appId;

    /**
     * 解密微信加密数据
     *
     * @param encryptedData 加密数据
     * @param sessionKey    会话密钥
     * @param iv            初始向量
     * @return 解密后的数据
     */
    public static String decryptData(String encryptedData, String sessionKey, String iv) {
        if (sessionKey == null){
            return null;
        }
        try {
            // Base64 解码
            byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
            byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
            byte[] ivBytes = Base64.getDecoder().decode(iv);

            // 初始化 AES 解密器
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(sessionKeyBytes, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            // 解密
            byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
            String decryptedData = new String(decryptedBytes, "UTF-8");

            // 验证 AppId
            if (!validateAppId(decryptedData)) {
                throw new RuntimeException("Invalid AppId");
            }
            return decryptedData;
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed", e);
        }
    }

    /**
     * 验证解密后的数据中的 AppId 是否匹配
     *
     * @param decryptedData 解密后的数据
     * @return 是否匹配
     */
    private static boolean validateAppId(String decryptedData) {
        try {
            // 解析 JSON 数据
            String appId = JsonParser.parseString(decryptedData)
                    .getAsJsonObject()
                    .getAsJsonObject("watermark")
                    .get("appid")
                    .getAsString();

            return appId.equals(appId);
        } catch (Exception e) {
            throw new RuntimeException("Invalid decrypted data format", e);
        }
    }
}
